<?php
//Cac bien su dung
class client_php 
{
	private $scheme 		= "";
	private $query 			= "";
	private $host			=	"";					// Hostname
	private $filename		= "";
	private $port			=	80;					// port
	
	private $proxy_host		=	"";					// proxy host
	private $proxy_port		=	"";					// proxy port
	private $agent			=	"";		// agent
	private	$referer		=	"";					// referer
	private $cookies		=	array();			// array cua cookie
	// $cookies["username"]="longnt";
	private	$rawheaders		=	array();			// array of raw headers
	// $rawheaders["Content-type"]="text/html";

	private $maxredirs		=	5;					// http redirection depth maximum. 0 = disable
	private $lastredirectaddr	=	"";				// chua dia chi redirect cuoi cung
	private	$offsiteok		=	true;				// allows redirection off-site
	private $maxframes		=	0;					// frame content depth maximum. 0 = disable
	private $expandlinks	=	true;				//
	//
	//
	private $passcookies	=	true;				//

	private	$user			=	"";					// user for http authen
	private	$pass			=	"";					// password for http authen

	// http accept types
	//private $accept			=	"image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
	private $accept				= "";
	private $results		=	"";					// Bien ket qua tra ve

	private $error			=	"";					// Bien error tra ve
	private	$response_code	=	"";					// response code returned from server
	private	$headers		=	array();			// headers returned from server sent here
	private	$maxlength		=	500000;				// Do lon du lieu tra ve
	private $read_timeout	=	0;					// Thoi gian time out (second )

	// 0 = disable timeout
	private $timed_out		=	false;				// Bien timeout
	private	$status			=	0;					//

	private	$curl_path		=	"/usr/local/bin/curl"; //Cai nay cho Linux thoi

	/**** Private privateiables ****/

	private	$_maxlinelen	=	4096;				// max line length (headers)

	private $_httpmethod	=	"GET";				// HTTP METHOD
	private $_httpversion	=	"HTTP/1.0";			// HTTP VERSION
	private $_submit_method	=	"POST";				// SUBMIT METHOD
	private $_submit_type	=	"application/x-www-form-urlencoded";	// SUBMIT TYPE
	private $_mime_boundary	=   "";					// MIME boundary for multipart/form-data submit type
	private $_redirectaddr	=	false;				// su dung khi fake la redirect
	private $_redirectdepth	=	0;					//
	private $_frameurls		= 	array();			//
	private $_framedepth	=	0;					//

	private $_isproxy		=	false;				//
	private $_fp_timeout	=	3;					//

	function getimage($document,$pathtoputfile,$id,$linkurl){
		$document = stripslashes($document);

		if ($this->getimageurl($document)){
			if (is_array($this->results)){
				for ($i=0;$i<count($this->results);$i++){
					//Thiendv edit ko upload file tren cung` sever.
					if(@fopen($this->results[$i],'r')){
						if(strtolower(substr($this->results[$i],0,4))=='http')
						{
							$this->getimagefile($this->results[$i],$pathtoputfile,$id,$i);
							$document  = str_replace($this->results[$i],$linkurl.$this->filename,$document);
						}
					}
				}
				return $document;
				break;
			}

			return $document;
			break;
		}

		return $document;
		break;
	}

	function getimageurl($documents){
		if ($this->GrabData("src=\"","\"",$documents,0)	){
			$results = $this->results;
			return true;
			break;

		}
		return false;
	}

	function getimagefile($urltofile,$pathtoputfile, $id,$stt){
		$path_parts = pathinfo($urltofile);
		$extension = $path_parts["extension"];
		if ($extension == ""){
			$extension = "jpg";
		}

		$this->filename = $id."_".$stt.".".$extension;

		if ($stt == "0")
		{
			$this->filename = $id.".".$extension;
		}

		$asd = new client_php();
		$asd->fetch($urltofile);
		$f  = fopen($pathtoputfile.$this->filename,"a");
		fwrite ($f,$asd->results);
		fclose($f);

		unset ($urltofile);
		unset ($pathtoputfile);
		unset ($id);
		unset ($stt);
		return true;
	}

	/*======================================================================*\
	Ham:	Grab($firstpos,$lastpost,$url)
	Cong dung:	Lay 1 doan du lieu tu 1 website
	Input:		$URI	Dia chi cua Site can lay , hoac doan text can lay
	$firstpos  Diem dau tien cua doan can lay
	$lastpos  Diem cuoi cua doan can lay
	$striptag (True , or False , lay ve HTML hoac strip tag HTML )
	Output:		$this->results	Ket qua tra ve duoi dang array (bat dau tu 0)
	\*======================================================================*/

	function GrabData($firstpos,$lastpost,$url,$striptag)
	{
		//unset privateiables
		$text = "";
		$this->results = "";
		$count = 0;
		$ketqua = "";

		// Neu URL la 1 Hypter Text Address

		$text = $url;

		$count = 0;

		while (true)
		{
			$posdau = strpos($text,$firstpos);

			$substring = substr($text,$posdau+strlen($firstpos),strlen($text)-$posdau);
			$poscuoi = strpos ($substring,$lastpost) + strlen($firstpos) +$posdau ;

			if (($posdau === false) or ($poscuoi === false ))
			{
				break;
			}

			$ketqua[$count] = substr ($text, $posdau+strlen($firstpos),$poscuoi - $posdau-strlen($firstpos));
			if ($striptag)
			{
				$ketqua[$count] = strip_tags($ketqua[$count]);
			}
			$count +=1;

			$text = substr($text,$poscuoi+strlen($lastpost),strlen($text)-$poscuoi);
		}

		$this->results = $ketqua;
		return true;
	}

	//Ham GrabData1 dung voi doi tuong UTF-8
	/*======================================================================*\
	Ham:	fetch($URI)
	Cong dung:	Lay du lieu tu 1 website
	Input:		$URI	Dia chi cua Site can lay
	Output:		$this->results	Ket qua tra ve
	\*======================================================================*/

	function fetch($URI)
	{
		$URI_PARTS = parse_url($URI);
		if(empty($URI_PARTS["query"]))
		$URI_PARTS["query"] = "";
		
		if (!empty($URI_PARTS["user"]))
		$this->user = $URI_PARTS["user"];
		
		if (!empty($URI_PARTS["pass"]))
		$this->pass = $URI_PARTS["pass"];

		switch($URI_PARTS["scheme"])
		{
			case "http":
			$this->host = $URI_PARTS["host"];
			if(!empty($URI_PARTS["port"]))
			$this->port = $URI_PARTS["port"];
			
			if($this->_connect($fp))
			{
				if($this->_isproxy)
				{
					// Proxy = true ?? Send URL
					$this->_httprequest($URI,$fp,$URI,$this->_httpmethod);
				}
				else
				{

					$path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");
					// no proxy, send only the path
					$this->_httprequest($path, $fp, $URI, $this->_httpmethod);
				}

				$this->_disconnect($fp);

				if($this->_redirectaddr)
				{
					/* url was redirected, Kiem tra do sa^u cua redirect */
					if($this->maxredirs > $this->_redirectdepth)
					{

						if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
						{

							$this->_redirectdepth++;
							$this->lastredirectaddr=$this->_redirectaddr;
							$this->fetch($this->_redirectaddr);
						}
					}
				}

				if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)
				{
					$frameurls = $this->_frameurls;
					$this->_frameurls = array();

					while(list(,$frameurl) = each($frameurls))
					{
						if($this->_framedepth < $this->maxframes)
						{
							$this->fetch($frameurl);
							$this->_framedepth++;
						}
						else
						break;
					}
				}
			}
			else
			{
				return false;
			}
			return true;
			break;
			case "https":
			if(!$this->curl_path || (!is_executable($this->curl_path)))
			return false;
			$this->host = $URI_PARTS["host"];
			if(!empty($URI_PARTS["port"]))
			$this->port = $URI_PARTS["port"];
			if($this->_isproxy)
			{
				// Proxy ?
				$this->_httpsrequest($URI,$URI,$this->_httpmethod);
			}
			else
			{
				$path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");

				$this->_httpsrequest($path, $URI, $this->_httpmethod);
			}

			if($this->_redirectaddr)
			{

				if($this->maxredirs > $this->_redirectdepth)
				{

					if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
					{

						$this->_redirectdepth++;
						$this->lastredirectaddr=$this->_redirectaddr;
						$this->fetch($this->_redirectaddr);
					}
				}
			}

			if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)
			{
				$frameurls = $this->_frameurls;
				$this->_frameurls = array();

				while(list(,$frameurl) = each($frameurls))
				{
					if($this->_framedepth < $this->maxframes)
					{
						$this->fetch($frameurl);
						$this->_framedepth++;
					}
					else
					break;
				}
			}
			return true;
			break;
			default:
				// Protocol Sai
				$this->error	=	'Invalid protocol "'.$URI_PARTS["scheme"].'"\n';
				return false;
				break;
		}
		return true;
	}

	/*======================================================================*\
	Private functions
	\*======================================================================*/

	/*======================================================================*\
	Ham:	_httprequest

	\*======================================================================*/

	function _httprequest($url,$fp,$URI,$http_method,$content_type="",$body="")
	{
		$cookie_headers = '';
		if($this->passcookies && $this->_redirectaddr)
		$this->setcookies();

		$URI_PARTS = parse_url($URI);
		if(empty($url))
		$url = "/";
		$headers = $http_method." ".$url." ".$this->_httpversion."\r\n";
		if(!empty($this->agent))
		$headers .= "User-Agent: ".$this->agent."\r\n";
		if(!empty($this->host) && !isset($this->rawheaders['Host']))
		$headers .= "Host: ".$this->host."\r\n";
		if(!empty($this->accept))
		$headers .= "Accept: ".$this->accept."\r\n";
		if(!empty($this->referer))
		$headers .= "Referer: ".$this->referer."\r\n";

		if(!empty($this->cookies))
		{
			if(!is_array($this->cookies))
			$this->cookies = (array)$this->cookies;

			reset($this->cookies);
			if ( count($this->cookies) > 0 ) {
				$cookie_headers .= 'Cookie: ';
				foreach ( $this->cookies as $cookieKey => $cookieVal ) {
					$cookie_headers .= $cookieKey."=".urlencode($cookieVal)."; ";
				}
				$headers .= substr($cookie_headers,0,-2) . "\r\n";
			}
		}
		if(!empty($this->rawheaders))
		{
			if(!is_array($this->rawheaders))
			$this->rawheaders = (array)$this->rawheaders;
			while(list($headerKey,$headerVal) = each($this->rawheaders))
			$headers .= $headerKey.": ".$headerVal."\r\n";
		}
		if(!empty($content_type)) {
			$headers .= "Content-type: $content_type";
			if ($content_type == "multipart/form-data")
			$headers .= "; boundary=".$this->_mime_boundary;
			$headers .= "\r\n";
		}
		if(!empty($body))
		$headers .= "Content-length: ".strlen($body)."\r\n";
		if(!empty($this->user) || !empty($this->pass))
		$headers .= "Authorization: Basic ".base64_encode($this->user.":".$this->pass)."\r\n";

		$headers .= "\r\n";

		// Set timeout khi request
		if ($this->read_timeout > 0)
		socket_set_timeout($fp, $this->read_timeout);
		$this->timed_out = false;

		fwrite($fp,$headers.$body,strlen($headers.$body));

		$this->_redirectaddr = false;
		unset($this->headers);

		while($currentHeader = fgets($fp,$this->_maxlinelen))
		{
			if ($this->read_timeout > 0 && $this->_check_timeout($fp))
			{
				$this->status=-100;
				return false;
			}

			if($currentHeader == "\r\n")
			break;


			if(preg_match("/^(Location:|URI:)/i",$currentHeader))
			{

				preg_match("/^(Location:|URI:)[ ]+(.*)/",chop($currentHeader),$matches);

				if(!preg_match("|\:\/\/|",$matches[2]))
				{

					$this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host.":".$this->port;

					if(!preg_match("|^/|",$matches[2]))
					$this->_redirectaddr .= "/".$matches[2];
					else
					$this->_redirectaddr .= $matches[2];
				}
				else
				$this->_redirectaddr = $matches[2];
			}

			if(preg_match("|^HTTP/|",$currentHeader))
			{
				if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$currentHeader, $status))
				{
					$this->status= $status[1];
				}
				$this->response_code = $currentHeader;
			}

			$this->headers[] = $currentHeader;
		}

		$results = '';
		do {
			$_data = fread($fp, $this->maxlength);
			if (strlen($_data) == 0) {
				break;
			}
			$results .= $_data;
		} while(true);

		if ($this->read_timeout > 0 && $this->_check_timeout($fp))
		{
			$this->status=-100;
			return false;
		}



		if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]+URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match))
		{
			$this->_redirectaddr = $this->_expandlinks($match[1],$URI);
		}


		if(($this->_framedepth < $this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i",$results,$match))
		{
			$this->results[] = $results;
			for($x=0; $x<count($match[1]); $x++)
			$this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host);
		}

		elseif(is_array($this->results))
		$this->results[] = $results;
		// no framed content
		else
		$this->results = $results;

		return true;
	}


	/*======================================================================*\
	Ham:	setcookies()
	Cong dung:	set cookies for a redirection
	\*======================================================================*/
	function setcookies()
	{
		for($x=0; $x<count($this->headers); $x++)
		{
			if(preg_match('/^set-cookie:[\s]+([^=]+)=([^;]+)/i', $this->headers[$x],$match))
			$this->cookies[$match[1]] = $match[2];
		}
	}


	/*======================================================================*\
	Ham:	_check_timeout (BOOLEAN)
	Cong dung:	Check neu time out
	Input:		$fp
	\*======================================================================*/

	function _check_timeout($fp)
	{
		if ($this->read_timeout > 0) {
			$fp_status = socket_get_status($fp);
			if ($fp_status["timed_out"]) {
				$this->timed_out = true;
				return true;
			}
		}
		return false;
	}

	/*======================================================================*\
	Function:	_connect
	Cong dung:	make a socket connection
	Input:		$fp	file connect
	\*======================================================================*/

	function _connect(&$fp)
	{
		if(!empty($this->proxy_host) && !empty($this->proxy_port))
		{
			$this->_isproxy = true;
			$host = $this->proxy_host;
			$port = $this->proxy_port;
		}
		else
		{
			$host = $this->host;
			$port = $this->port;
		}

		$this->status = 0;

		if($fp = fsockopen($host,$port,$errno,$errstr,$this->_fp_timeout))
		{
			// socket connection succeeded
			return true;
		}
		else
		{
			// socket connection failed
			$this->status = $errno;
			switch($errno)
			{
				case -3:
				$this->error="socket creation failed (-3)";
				case -4:
				$this->error="dns lookup failure (-4)";
				case -5:
				$this->error="connection refused or timed out (-5)";
				default:
				$this->error="connection failed (".$errno.")";
			}
			return false;
		}
	}
	
	/*======================================================================*\
	Function:	_disconnect
	Cong dung:	disconnect a socket connection
	Input:		$fp	file pointer
	\*======================================================================*/

	function _disconnect($fp)
	{
		return(fclose($fp));
	}

	/*======================================================================*\
	Function:	_prepare_post_body
	Cong dung:	Prepare post body according to encoding type
	Input:		$formprivates  - form privateiables
	$formfiles - form upload files
	Output:		post body
	\*======================================================================*/

	function _prepare_post_body($formprivates, $formfiles)
	{
		settype($formprivates, "array");
		settype($formfiles, "array");

		if (count($formprivates) == 0 && count($formfiles) == 0)
		return;

		switch ($this->_submit_type) 
		{
			case "application/x-www-form-urlencoded":
			reset($formprivates);
			while(list($key,$val) = each($formprivates)) {
				if (is_array($val) || is_object($val)) {
					while (list($cur_key, $cur_val) = each($val)) {
						$postdata .= urlencode($key)."[]=".urlencode($cur_val)."&";
					}
				} else
				$postdata .= urlencode($key)."=".urlencode($val)."&";
			}
			break;

			case "multipart/form-data":
			$this->_mime_boundary = "Snoopy".md5(uniqid(microtime()));

			reset($formprivates);
			while(list($key,$val) = each($formprivates)) {
				if (is_array($val) || is_object($val)) {
					while (list($cur_key, $cur_val) = each($val)) {
						$postdata .= "--".$this->_mime_boundary."\r\n";
						$postdata .= "Content-Disposition: form-data; name=\"$key\[\]\"\r\n\r\n";
						$postdata .= "$cur_val\r\n";
					}
				} else {
					$postdata .= "--".$this->_mime_boundary."\r\n";
					$postdata .= "Content-Disposition: form-data; name=\"$key\"\r\n\r\n";
					$postdata .= "$val\r\n";
				}
			}

			reset($formfiles);
			while (list($field_name, $file_names) = each($formfiles)) {
				settype($file_names, "array");
				while (list(, $file_name) = each($file_names)) {
					if (!is_readable($file_name)) continue;

					$fp = fopen($file_name, "r");
					$file_content = fread($fp, filesize($file_name));
					fclose($fp);
					$base_name = basename($file_name);

					$postdata .= "--".$this->_mime_boundary."\r\n";
					$postdata .= "Content-Disposition: form-data; name=\"$field_name\"; filename=\"$base_name\"\r\n\r\n";
					$postdata .= "$file_content\r\n";
				}
			}
			$postdata .= "--".$this->_mime_boundary."--\r\n";
			break;
		}

		return $postdata;
	}
}
?>
